package dao;

import interfaces.IDaoGenerico;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;

import util.Conexao;

public abstract class DaoGenerico<T> implements IDaoGenerico<T> {

	private Class clazz;
	
	public DaoGenerico() {
		this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
	
	public T salvar(T obj) {
		Session session = Conexao.getSessionFactory().openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.save(obj);
			transaction.commit();
			session.refresh(obj);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally {
			session.close();
		}
		return null;
	}

	public T atualizar(T obj) {
		Session session = Conexao.getSessionFactory().openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.update(obj);
			transaction.commit();
			session.refresh(obj);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally {
			session.close();
		}
		return null;
	}

	public T remover(T obj) {
		Session session = Conexao.getSessionFactory().openSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.delete(obj);
			transaction.commit();
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			transaction.rollback();
		} finally {
			session.close();
		}
		return null;
	}

	public Criteria getCriteria() {
		Session session = Conexao.getSessionFactory().openSession();
		Criteria criteria = session.createCriteria(clazz);
		return criteria;
	}

	public List<T> listar() {
		Session session = Conexao.getSessionFactory().openSession();
		List<T> objts = null;
		try {
			Criteria selectAll = session.createCriteria(clazz);
			objts = selectAll.list();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return objts;
	}
}
